home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / AlertLib / AlertNotificationLib.c < prev   
Encoding:
C/C++ Source or Header  |  1993-03-22  |  5.3 KB  |  218 lines  |  [TEXT/KAHL]

  1. /*    Functions for displaying an alert using the notification manager. Two
  2.     functions are provided, one for use from an application and the other
  3.     for use from an INIT.
  4.     
  5.     Bugs: The notification manager alert posted from an INIT allocates
  6.     some memory in the system heap which is never disposed of. The UMPG
  7.     contains some code which shows how to dispose of the memory, but
  8.     I haven't incorporated it into this file.
  9.      
  10.     Revision History:
  11.     
  12.     91/06/05 AIH
  13.     - Fixed a few comments
  14.     
  15.     91/04/21 AIH
  16.     - Slightly changed names of the external functions
  17.     
  18.     91/03/23 AIH
  19.     - Adapted for 7.0 header files
  20.     
  21.     91/03/06 AIH
  22.     - Added support for extra response function
  23.     
  24.     91/03/02 AIH
  25.     - Added test for system 6.0
  26.     
  27.     91/01/25 AIH
  28.     - Rewrote to support small icons
  29.     
  30.     91/01/20 AIH
  31.     - Added calls to GlobalSetup and GlobalRestore
  32.     
  33.     91/01/05 Ari Halberstadt (AIH)
  34.     - Inserted this standard header in all files */
  35.  
  36. #include <string.h>
  37. #include "MacLib.h"
  38. #include "MemoryLib.h"
  39. #include "StringLib.h"
  40. #include "AlertLib.h"
  41.  
  42. /* A pointer to this structure is placed in the notification record's refCon
  43.     field. It stores a pointer to the application's extra response
  44.     function. */
  45. struct ExtraResponse {
  46.     ProcPtr    response;
  47.     void        *data;
  48. };
  49.  
  50. /* load and detach the 'SICN' resource */
  51. static Handle LoadSicn(short sicnid)
  52. {
  53. BEGIN
  54.     Handle sicn;
  55.     
  56.     sicn = GetResource('SICN', sicnid);
  57.     if (sicn) {
  58.         HNoPurge(sicn);
  59.         DetachResource(sicn);
  60.         if (ResError())
  61.             sicn = NULL;
  62.     }
  63.     return(sicn);
  64. END
  65. }
  66.  
  67. /* Post a notification manager alert containing the string and use the
  68.     'SICN' with the specified ID, or no 'SICN' if the ID is 0. The 'response'
  69.     parameter should be the response function to call, or -1L to use
  70.     the Notification Manager's default function. */
  71. static void AlertNotify(const CStr255 str, short sicnid, ProcPtr response,
  72.     struct ExtraResponse *extra)
  73. {
  74. BEGIN
  75.     NMRec            *nm = NULL;
  76.     StringPtr    nmStr = NULL;
  77.     Handle        nmIcon = NULL;
  78.     OSErr            err = noErr;
  79.  
  80.     require(StrValid(str, sizeof(CStr255)));
  81.     require(response == (ProcPtr) -1 || response != NULL);
  82.     
  83.     /* make sure the notification manager is available */
  84.     if (MacHasNotificationMgr()) {
  85.     
  86.         /* remember base register to global variables */
  87.         GlobalRemember();
  88.     
  89.         /* load the sicn if one is specified */
  90.         if (sicnid)
  91.             nmIcon = LoadSicn(sicnid);
  92.         
  93.         /* allocate notification record */
  94.         nm = (NMRec *) NewPtrClear(sizeof(NMRec));
  95.         err = MemError();
  96.         if (! err) {
  97.         
  98.             /* allocate string */
  99.             nmStr = (StringPtr) NewPtr(strlen(str)+1);
  100.             err = MemError();
  101.             if (! err) {
  102.             
  103.                 /* fill in fields of notification record */
  104.                 CtoPstr(strcpy((char*)nmStr, str));
  105.                 nm->qType = nmType;
  106.                 nm->nmIcon = nmIcon;
  107.                 nm->nmStr = nmStr;
  108.                 nm->nmResp = response;
  109.                 nm->nmRefCon = (long) extra;
  110.                 err = NMInstall((void *) nm);
  111.             }
  112.         }
  113.         
  114.         /* cleanup */
  115.         if (err) {
  116.             if (nm) DisposPtr((Ptr) nm);
  117.             if (nmStr) DisposPtr((Ptr) nmStr);
  118.             if (nmIcon) DisposHandle((Handle) nmIcon);
  119.         }
  120.     }
  121. END
  122. }
  123.     
  124. /* response procedure for Notification Manager */
  125. static pascal void NMResponse(QElemPtr qp)
  126. {
  127. BEGIN
  128.     NMRec *nm = (NMRec *) qp;
  129.     struct ExtraResponse *extra;
  130.     
  131.     /* setup base register to global variables */
  132.     GlobalSetup();
  133.  
  134.     /* remove notification */
  135.     if (NMRemove((void *) nm) == noErr) {
  136.     
  137.         /* get extra response function */
  138.         extra = (struct ExtraResponse *) nm->nmRefCon;
  139.         if (extra) {
  140.         
  141.             /* call extra response function and dispose of extra pointer */
  142.             extra->response(extra->data);
  143.             DisposPtr((Ptr) extra);
  144.         }
  145.         
  146.         /* dispose of notification */
  147.         if (nm->nmStr)
  148.             DisposPtr((Ptr) nm->nmStr);
  149.  
  150.         if (nm->nmIcon)
  151.             DisposHandle((Handle) nm->nmIcon);
  152.  
  153.         DisposPtr((Ptr) nm);
  154.     }
  155.     
  156.     /* restore base register to global variables */
  157.     GlobalRestore();
  158. END
  159. }
  160.  
  161. /* Use Notification Manager to display an alert containing the given
  162.     string. If 'sicnid' is non-zero then a 'SICN' resource with the
  163.     id is loaded and installed in the notification. If the 'response'
  164.     parameter is non-null, it should contain a pointer to a function
  165.     which will be called just after the notification has been removed
  166.     from the queue. This "extra" response function should be declared
  167.     as follows:
  168.         
  169.         void response(void *data)
  170.         
  171.     The 'data' parameter may contain anything the application puts in it,
  172.     sinze it will be passed to the extra response function. */
  173. void AlertNotification(const CStr255 str, short sicnid, ProcPtr response,
  174.     void *data)
  175. {
  176. BEGIN
  177.     struct ExtraResponse *extra;
  178.     
  179.     require(StrValid(str, sizeof(CStr255)));
  180.     
  181.     /* create extra response structure */
  182.     extra = NULL;
  183.     if (response) {
  184.         extra = (struct ExtraResponse *) NewPtr(sizeof(struct ExtraResponse));
  185.         if (extra) {
  186.             extra->response = response;
  187.             extra->data = data;
  188.         }
  189.     }
  190.     AlertNotify(str, sicnid, (ProcPtr) NMResponse, extra);
  191. END
  192. }
  193.  
  194. /* same as AlertNotification but works with an INIT */
  195. void AlertNotificationINIT(const CStr255 str, short sicnid)
  196. {
  197. BEGIN
  198.     THz oldzone;
  199.  
  200.     require(StrValid(str, sizeof(CStr255)));
  201.     
  202.     /* set current zone to System zone so that all the memory allocated will be
  203.         around even after the INIT has exited; this causes some wasted space, but
  204.         there's no simple way around this problem */
  205.     oldzone = (THz) GetZone();
  206.     SetZone(SystemZone());
  207.     
  208.     /* post the notification using the default response procedure since
  209.         the INIT's code won't be around by the time the response procedure
  210.         is called */
  211.     AlertNotify(str, sicnid, (ProcPtr) -1, NULL);
  212.     
  213.     /* restore old heap zone */
  214.     SetZone(oldzone);
  215. END
  216. }
  217.  
  218.